/**
 * Created by leo on 2017/10/17.
 * 读写锁 使用的悲观的锁策略, 如果有大量的读线程依然会导致写线程的 "饥饿"
 * 而StampedLock提供了一种乐观的读策略. 这种乐观的锁非常类似无锁的操作,使得乐观锁完全不会阻塞写线程.
 *
 *
 * StampedLock内部实现是基于CLH锁的. CLH是一种自旋锁, 它保证没有 "饥饿" 发生.
 * 并且可以保证FIFO (First-In-First-Out) 的服务顺序.
 * CLH基本思想如下:
 *     锁维护一个等待线程队列,所有申请锁但是没有成功的线程都记录在这个队列中.
 *   每一个节点(一个节点代表一个线程),保存一个标记位(locked),用于判断当前线程是否已经释放锁.
 *     当一个线程试图获取锁时,取得当前等待队列的尾部节点作为其前序节点, 并使用类似如下代码判断
 *   前序节点是否已经成功释放锁:
 *      while(pred.locked){}
 *     只要前序节点(pred)没有释放锁, 则表示当前线程还不能继续执行, 因此会自旋等待.
 *     反之,前序节点已经释放锁,则当前线程可以继续执行.
 *     释放锁时, 也遵循这个逻辑, 线程会将自身节点位置的locked设置为false, 那么后续等待的线程就可以继续执行了.
 */
package org.xqh.study.juc.lock.stampedLock;